using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using ThridGroup.ERP.Application.Contracts.DTO;
using ThridGroup.ERP.Application.Contracts.ProductionSystem;
using Volo.Abp.Application.Services;
using Volo.Abp.Domain.Repositories;
using Microsoft.Extensions.Logging;
using Microsoft.EntityFrameworkCore;
using ThridGroup.ERP.ProductionSystem;

namespace ThridGroup.ERP.Application.ProductionSystem
{
    public class ProductionReportingService : ApplicationService, IProductionReportingService
    {
        private readonly IRepository<ProductionReporting, int> _productionReportingRepository;
        private readonly ILogger<ProductionReportingService> _logger;

        public ProductionReportingService(
            IRepository<ProductionReporting, int> productionReportingRepository,
            ILogger<ProductionReportingService> logger)
        {
            _productionReportingRepository = productionReportingRepository;
            _logger = logger;
        }

        /// <summary>
        /// 添加生产报工
        /// </summary>
        public async Task<int> AddProductionReporting(ProductionReportingDto dto)
        {
            try
            {
                _logger.LogInformation($"开始添加生产报工：工单编号={dto.ProductionWorkOrderCode}, 产品编码={dto.ProductMaterialCode}");

                // 验证输入
                ValidateProductionReportingInput(dto);
                
                // 创建新实体
                var entity = new ProductionReporting
                {
                    ReportingType = dto.ReportingType,
                    ProductionWorkOrderCode = dto.ProductionWorkOrderCode,
                    ProductMaterialCode = dto.ProductMaterialCode,
                    ProductMaterialName = dto.ProductMaterialName,
                    ProductModel = dto.ProductModel,
                    ReportingQuantity = dto.ReportingQuantity,
                    Reporter = dto.Reporter,
                    ReportingTime = dto.ReportingTime,
                    Approver = dto.Approver ?? string.Empty,
                    Remark = dto.Remark ?? string.Empty,
                    Recorder = dto.Recorder,
                    RecordCreateTime = DateTime.Now,
                    RecordUpdateTime = DateTime.Now
                };

                _logger.LogInformation($"准备插入数据库：工单编号={entity.ProductionWorkOrderCode}");
                
                var result = await _productionReportingRepository.InsertAsync(entity, true);
                
                if (result == null || result.Id <= 0)
                {
                    throw new Exception("插入成功但未返回有效ID");
                }
                
                _logger.LogInformation($"生产报工添加成功，ID：{result.Id}");
                return result.Id;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"添加生产报工失败：{ex.Message}");
                throw new Exception($"添加生产报工失败：{ex.Message}", ex);
            }
        }

        /// <summary>
        /// 更新生产报工
        /// </summary>
        public async Task<int> UpdateProductionReporting(ProductionReportingDto dto)
        {
            try
            {
                _logger.LogInformation($"开始更新生产报工，ID：{dto.Id}");

                if (dto.Id <= 0)
                {
                    throw new ArgumentException("无效的生产报工ID");
                }

                ValidateProductionReportingInput(dto);
                
                var entity = await _productionReportingRepository.GetAsync(dto.Id);
                
                if (entity == null)
                {
                    throw new Exception($"未找到ID为{dto.Id}的生产报工");
                }

                // 更新实体属性
                entity.ReportingType = dto.ReportingType;
                entity.ProductionWorkOrderCode = dto.ProductionWorkOrderCode;
                entity.ProductMaterialCode = dto.ProductMaterialCode;
                entity.ProductMaterialName = dto.ProductMaterialName;
                entity.ProductModel = dto.ProductModel;
                entity.ReportingQuantity = dto.ReportingQuantity;
                entity.Reporter = dto.Reporter;
                entity.ReportingTime = dto.ReportingTime;
                entity.Approver = dto.Approver ?? string.Empty;
                entity.Remark = dto.Remark ?? string.Empty;
                entity.Recorder = dto.Recorder;
                entity.RecordUpdateTime = DateTime.Now;

                await _productionReportingRepository.UpdateAsync(entity, true);
                
                _logger.LogInformation($"生产报工更新成功，ID：{entity.Id}");
                return entity.Id;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"更新生产报工失败：{ex.Message}");
                throw new Exception($"更新生产报工失败：{ex.Message}", ex);
            }
        }

        /// <summary>
        /// 删除生产报工
        /// </summary>
        public async Task DeleteProductionReporting(int id)
        {
            try
            {
                _logger.LogInformation($"开始删除生产报工，ID：{id}");

                if (id <= 0)
                {
                    throw new ArgumentException("无效的生产报工ID");
                }

                var entity = await _productionReportingRepository.GetAsync(id);
                
                if (entity == null)
                {
                    throw new Exception($"未找到ID为{id}的生产报工");
                }

                await _productionReportingRepository.DeleteAsync(entity, true);
                
                _logger.LogInformation($"生产报工删除成功，ID：{id}");
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"删除生产报工失败：{ex.Message}");
                throw new Exception($"删除生产报工失败：{ex.Message}", ex);
            }
        }

        /// <summary>
        /// 获取单个生产报工
        /// </summary>
        public async Task<ProductionReportingDto> GetProductionReporting(int id)
        {
            try
            {
                _logger.LogInformation($"开始获取生产报工，ID：{id}");

                if (id <= 0)
                {
                    throw new ArgumentException("无效的生产报工ID");
                }

                var entity = await _productionReportingRepository.GetAsync(id);
                
                if (entity == null)
                {
                    throw new Exception($"未找到ID为{id}的生产报工");
                }

                var dto = MapToDto(entity);
                _logger.LogInformation($"成功获取生产报工，ID：{id}");
                return dto;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"获取生产报工失败，ID：{id}");
                throw new Exception($"获取生产报工失败：{ex.Message}", ex);
            }
        }

        /// <summary>
        /// 获取所有生产报工
        /// </summary>
        public async Task<List<ProductionReportingDto>> GetProductionReportings()
        {
            try
            {
                _logger.LogInformation("开始获取生产报工列表");

                var queryable = await _productionReportingRepository.GetQueryableAsync();
                var entities = await queryable.OrderByDescending(x => x.RecordCreateTime).ToListAsync();

                var dtos = entities.Select(MapToDto).ToList();
                
                _logger.LogInformation($"成功获取生产报工列表，共{dtos.Count}条记录");
                return dtos;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取生产报工列表失败");
                throw new Exception($"获取生产报工列表失败：{ex.Message}", ex);
            }
        }

        /// <summary>
        /// 验证输入
        /// </summary>
        private void ValidateProductionReportingInput(ProductionReportingDto dto)
        {
            if (string.IsNullOrWhiteSpace(dto.ProductionWorkOrderCode))
            {
                throw new ArgumentException("生产工单编号不能为空");
            }

            if (string.IsNullOrWhiteSpace(dto.ProductMaterialCode))
            {
                throw new ArgumentException("产品物料编码不能为空");
            }

            if (string.IsNullOrWhiteSpace(dto.ProductMaterialName))
            {
                throw new ArgumentException("产品物料名称不能为空");
            }

            if (dto.ReportingQuantity <= 0)
            {
                throw new ArgumentException("报工数量必须大于0");
            }

            if (string.IsNullOrWhiteSpace(dto.Reporter))
            {
                throw new ArgumentException("报工人不能为空");
            }
        }

        /// <summary>
        /// 实体映射到DTO
        /// </summary>
        private ProductionReportingDto MapToDto(ProductionReporting entity)
        {
            return new ProductionReportingDto
            {
                Id = entity.Id,
                ReportingType = entity.ReportingType,
                ProductionWorkOrderCode = entity.ProductionWorkOrderCode,
                ProductMaterialCode = entity.ProductMaterialCode,
                ProductMaterialName = entity.ProductMaterialName,
                ProductModel = entity.ProductModel,
                ReportingQuantity = entity.ReportingQuantity,
                Reporter = entity.Reporter,
                ReportingTime = entity.ReportingTime,
                Approver = entity.Approver,
                Remark = entity.Remark,
                Recorder = entity.Recorder,
                RecordCreateTime = entity.RecordCreateTime,
                RecordUpdateTime = entity.RecordUpdateTime
            };
        }
    }
} 